#ifndef _ML_KMEANS_DATA_CLUSTERING_H_
#define _ML_KMEANS_DATA_CLUSTERING_H_
#include "MLCommon.h"
#include "MLDataClustering.h"
#include "MLDataSet.h"
_MYLABLIB_BEGIN

class CMLClustering_KMeans : public CMLDataClustering
{
public:
	// Constructor and Destructor
	CMLClustering_KMeans(void);
	~CMLClustering_KMeans(void);

public:
	// Interfaces
	int SetParameters(const std::wstring& wstrParams);
	int DoClustering(const CMLDataSet& dataSet, std::vector<CMLDataCluster>& vClusters);

public:
	// Extra Methods
	int DoClustering(const CMLDataSet& dataSet, const std::vector<double>& vWeights, std::vector<CMLDataCluster>& vClusters);

public:
	// Properites
	inline void SetK(int nK) { m_nK = nK; };
	inline int  GetK(void) { return m_nK; };

private:
	// Implementations
	int  RandomInitCenters(const CMLDataSet& dataSet);
	int  ConvergeAllPoints(const CMLDataSet& dataSet, std::vector<std::vector<int>>& vClusters);
	bool IsClutersDifferent(const std::vector<std::vector<int>>& vClusters1, std::vector<std::vector<int>>& vClusters2);
	int  ResetCenters(const CMLDataSet& dataSet, std::vector<std::vector<int>>& vClusters);
	int  ResetCentersWithWeights(const CMLDataSet& dataSet, const std::vector<double>& vWeights, std::vector<std::vector<int>>& vClusters);


private:
	// Fields
	int m_nK;
	std::vector<CMLDataPoint> m_vCenters;
};

_MYLABLIB_END
#endif
